{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 连接"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 普通连接\n",
    "```python\n",
    "def __init__(self, host='localhost', port=6379,\n",
    "             db=0, password=None, socket_timeout=None,\n",
    "             socket_connect_timeout=None,\n",
    "             socket_keepalive=None, socket_keepalive_options=None,\n",
    "             connection_pool=None, unix_socket_path=None,\n",
    "             encoding='utf-8', encoding_errors='strict',\n",
    "             charset=None, errors=None,\n",
    "             decode_responses=False, retry_on_timeout=False,\n",
    "             ssl=False, ssl_keyfile=None, ssl_certfile=None,\n",
    "             ssl_cert_reqs='required', ssl_ca_certs=None,\n",
    "             max_connections=None):\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bar\n"
     ]
    }
   ],
   "source": [
    "import redis\n",
    "\n",
    "host = 'localhost'\n",
    "port = 6379\n",
    "\n",
    "r = redis.Redis(host=host, port=port, decode_responses=True)\n",
    "\n",
    "r.set('foo', 'bar')\n",
    "print(r.get('foo'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 连接池\n",
    "\n",
    "避免每次建立、释放连接的开销\n",
    "\n",
    "默认，每个Redis实例都会维护一个自己的连接池。\n",
    "\n",
    "可以直接建立一个连接池，然后作为参数Redis，这样就可以实现多个Redis实例共享一个连接池。　"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import redis\n",
    "\n",
    "host = 'localhost'\n",
    "port = 6379\n",
    "\n",
    "pool = redis.ConnectionPool(host=host, port=port, decode_responses=True)\n",
    "\n",
    "r = redis.Redis(connection_pool=pool)\n",
    "\n",
    "r.set('foo', 'bar')\n",
    "print(r.get('foo'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## String\n",
    "### set(name, value, ex=None, px=None, nx=False, xx=False)\n",
    "\n",
    "在Redis中设置值，默认，不存在则创建，存在则修改\n",
    "参数：\n",
    " - ex，过期时间（秒）\n",
    " - px，过期时间（毫秒）\n",
    " - nx，如果设置为True，则只有name不存在时，当前set操作才执行\n",
    " - xx，如果设置为True，则只有name存在时，当前set操作才执行"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置一个k-v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bigberg\n"
     ]
    }
   ],
   "source": [
    "r.set('name', 'bigberg')\n",
    "print(r.get('name'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置过期时间为2秒\n",
    "2 秒后获取该值为None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bigberg\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "\n",
    "r.set('name', 'bigberg', ex=2)\n",
    "print(r.get('name'))\n",
    "time.sleep(2)\n",
    "print(r.get('name'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### setnx(name, value)\n",
    "\n",
    "设置值，只有name不存在时，执行设置操作（添加）\n",
    " \n",
    "如果是r.setnx('name', 'Tom') 则name的值还是'bigberg'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.setnx('name', 'Tom')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### setex(name, time, value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.setex('name', 2, 'Jack')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### psetex(name, time_ms, value)\n",
    "\n",
    "参数：\n",
    "- time_ms，过期时间（数字毫秒 或 timedelta对象）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.psetex('name', 2000, 'Jack')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### mset(mapping)\n",
    "\n",
    "批量设置值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "print(r.mset({'a': 1, 'b': 2}))\n",
    "print(r.get('a'))\n",
    "print(r.get('b'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### get(name)　\n",
    "\n",
    "获取值\n",
    "\n",
    "### mget(keys, *args)\n",
    "\n",
    "批量获取\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['1', '2']\n"
     ]
    }
   ],
   "source": [
    "print(r.mget('a', 'b'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### getset(name, value)\n",
    "\n",
    "设置新值并获取原来的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "Tom\n"
     ]
    }
   ],
   "source": [
    "print(r.getset('name', 'Tom'))\n",
    "print(r.get('name'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### getrange(key, start, end)\n",
    "\n",
    "如果是中文字符，在utf-8编码下，一个中文字符占3个字节"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "杭州\n",
      "杭\n"
     ]
    }
   ],
   "source": [
    "r.set('address', '杭州')\n",
    "print(r.getrange('address', 0, -1))\n",
    "print(r.getrange('address', 0, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### setrange(name, offset, value)\n",
    "\n",
    "修改字符串内容，从指定字符串索引开始向后替换（新值太长时，则向后添加）\n",
    "\n",
    "参数：\n",
    "- offset，字符串的索引，字节（一个汉字三个字节）\n",
    "- value，要设置的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "苏州\n"
     ]
    }
   ],
   "source": [
    "r.setrange('address', 0, '苏')\n",
    "print(r.get('address'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tom\n",
      "Tool\n"
     ]
    }
   ],
   "source": [
    "print(r.get('name'))\n",
    "r.setrange('name', 2, 'ol')\n",
    "print(r.get('name'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### setbit(name, offset, value)\n",
    "\n",
    "对name对应值的二进制表示的位进行操作\n",
    "  \n",
    "```\n",
    "# 对name对应值的二进制表示的位进行操作\n",
    "  \n",
    "# 参数：\n",
    "    # name，redis的name\n",
    "    # offset，位的索引（将值变换成二进制后再进行索引）\n",
    "    # value，值只能是 1 或 0\n",
    "  \n",
    "# 注：如果在Redis中有一个对应： n1 = \"foo\"，\n",
    "        那么字符串foo的二进制表示为：01100110 01101111 01101111\n",
    "    所以，如果执行 setbit('n1', 7, 1)，则就会将第7位设置为1，\n",
    "        那么最终二进制则变成 01100111 01101111 01101111，即：\"goo\"\n",
    "        \n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tool\n",
      "Pool\n"
     ]
    }
   ],
   "source": [
    "print(r.get('name'))\n",
    "r.setbit('name', 5, 0)\n",
    "print(r.get('name'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### getbit(name, offset)\n",
    "\n",
    "获取name对应的值的二进制表示中的某位的值 （0或1）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Pool'"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r.get('name')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "print(r.getbit('name', 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### bitcount(key, start=None, end=None)\n",
    "\n",
    "获取name对应的值的二进制表示中 1 的个数\n",
    "\n",
    "参数：\n",
    "-  key，Redis的name\n",
    "- start，位起始位置\n",
    "- end，位结束位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "18\n"
     ]
    }
   ],
   "source": [
    "print(r.bitcount('name', 0, 20))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### strlen(name)\n",
    "\n",
    "返回name对应值的字节长度（一个汉字3个字节）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "苏州\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "print(r.get('address'))\n",
    "print(r.strlen('address'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### incr(name, amount=1)\n",
    "\n",
    "自增 name对应的值，当name不存在时，则创建name＝amount，否则，则自增。\n",
    "  \n",
    "参数：\n",
    "- name,Redis的name\n",
    "- amount,自增数（必须是整数）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(r.incr('login_user'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### incrbyfloat(name, amount=1.0)\n",
    "\n",
    "自增 name对应的值，当name不存在时，则创建name＝amount，否则，则自增。\n",
    "  \n",
    "参数：\n",
    "- name,Redis的name\n",
    "- amount,自增数（浮点型）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.2\n",
      "2.4\n",
      "3.6\n",
      "4.8\n",
      "6.0\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(r.incrbyfloat('num', 1.2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### decr(name, amount=1)\n",
    "\n",
    "自减 name对应的值，当name不存在时，则创建name＝amount，否则，则自减。\n",
    "  \n",
    "参数：\n",
    "- name,Redis的name\n",
    "- amount,自减数（整数）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "3\n",
      "2\n",
      "1\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(r.decr('login_user'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### append(key, value)\n",
    "\n",
    "在redis name对应的值后面追加内容\n",
    "  \n",
    "参数：\n",
    "- key, redis的name\n",
    "- value, 要追加的字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "苏州\n",
      "15\n",
      "苏州西湖区\n"
     ]
    }
   ],
   "source": [
    "print(r.get('address'))\n",
    "print(r.append('address', '西湖区'))\n",
    "print(r.get('address'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hash"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "position": {
    "height": "310px",
    "left": "996px",
    "right": "20px",
    "top": "120px",
    "width": "350px"
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
